package org.ehe.business.overdue.extract;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.ehe.business.engineer.domain.EngineerEntity;
import org.ehe.business.engineer.service.EngineerService;
import org.ehe.business.monitor.DataExtractor;
import org.ehe.business.monitor.MonitorData;
import org.ehe.business.overdue.config.OverdueStatus;
import org.ehe.business.overdue.domain.OverdueRecord;
import org.ehe.business.overdue.mapper.OverdueRecordMapper;
import org.ehe.business.project.domain.ProjectEntity;
import org.ehe.business.project.domain.dto.ProjectCreateRequest;
import org.ehe.business.project.mapper.ProjectMapper;
import org.ehe.business.timeout.contants.BizTypeConstant;
import org.ehe.business.timeout.domain.SsePushMessage;
import org.ehe.business.timeout.domain.TimeoutInstance;
import org.ehe.business.timeout.mapper.SsePushMessageMapper;
import org.ehe.business.timeout.mapper.TimeoutInstanceMapper;
import org.ehe.common.core.domain.R;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.satoken.utils.LoginHelper;
import org.ehe.common.sse.dto.SseMessageDto;
import org.ehe.common.sse.utils.SseMessageUtils;
import org.ehe.erp.domain.purchase.ErpPurchaseOrder;
import org.ehe.erp.enums.ErpAuditStatus;
import org.ehe.system.domain.vo.SysUserVo;
import org.ehe.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 项目管理参数解析
 * @author :zhangnn
 * @className :ProjectDataExtractor
 * @description: TODO
 * @date 2025-10-13 13:56:33
 */
@Slf4j
@Component
public class ProjectDataExtractor implements DataExtractor {

    // 注入ProjectMapper，用于从数据库查询项目信息（补充缺失的字段）
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ScheduledExecutorService scheduledExecutorService;
    @Autowired
    private EngineerService engineerService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SsePushMessageMapper ssePushMessageMapper;
//    @Autowired
//    private TimeoutInstanceMapper timeoutInstanceMapper;
    @Autowired
    private OverdueRecordMapper overdueRecordMapper;

    @Override
    public MonitorData extract(JoinPoint joinPoint, Object result) {
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            log.error("接口无参数，提取失败");
            return null;
        }

        Long bizId = null;
        String status = null;
        ProjectCreateRequest request = null;
        boolean isPathVarOnly = false; // 是否是纯路径变量接口（如/updateProjectStatus）

        if (args.length == 1
            && args[0] instanceof Long) {
            bizId = (Long) args[0];
            isPathVarOnly = true; // 标记为纯路径变量接口
        }
        // 场景1：纯路径变量接口（2个参数：Long projectId + int estimatedHours）
        else if (args.length == 2
            && args[0] instanceof Long
            && args[1] instanceof Integer) {
            bizId = (Long) args[0];
            isPathVarOnly = true; // 标记为纯路径变量接口
        } else if (args.length == 2
            && args[0] instanceof Long
            && args[1] instanceof String) {
            bizId = (Long) args[0];
            isPathVarOnly = true; // 标记为纯路径变量接口
        }
        // 场景2：1个参数（新增接口：ProjectCreateRequest）
        else if (args.length == 1 && args[0] instanceof ProjectCreateRequest) {
            request = (ProjectCreateRequest) args[0];
            status = request.getApproveStatus();
            bizId = getBizIdFromResult(result); // 从返回值取id
        }
        // 场景3：2个参数（更新接口：Long projectId + ProjectCreateRequest）
        else if (args.length == 2
            && (args[0] instanceof Long || args[0] instanceof Integer)
            && args[1] instanceof ProjectCreateRequest) {
            // 处理projectId（兼容Long/Integer）
            Object projectIdObj = args[0];
            bizId = (projectIdObj instanceof Long) ? (Long) projectIdObj : ((Integer) projectIdObj).longValue();
            request = (ProjectCreateRequest) args[1];
            status = request.getStatus();
        } else {
            log.error("未匹配的参数结构，参数类型：{}", Arrays.stream(args).map(a -> a.getClass().getName()).collect(Collectors.toList()));
            return null;
        }

        // 校验bizId是否存在
        if (bizId == null) {
            log.error("bizId获取失败");
            return null;
        }

        // 补充字段：从请求体或数据库查询获取bizName、createTime等
        MonitorData data = new MonitorData();
        data.setBizId(bizId);
        data.setStatus(status);

        // 情况1：有请求体（场景2、3），从请求体取字段
        if (request != null || isPathVarOnly) {
//            data.setStatus(request.getApproveStatus());
//            data.setBizName(request.getProjectName());
//            data.setCreateTime(LocalDateTime.now());
//        }
//        // 情况2：纯路径变量接口（场景1），从数据库查询补充字段
//        else if (isPathVarOnly) {
            // 从数据库查询项目信息（需ProjectMapper提供查询方法）
            ProjectEntity project = projectMapper.selectById(bizId);
            if (project == null) {
                log.error("项目不存在，projectId：{}", bizId);
                return null;
            }
            data.setBizName(project.getProjectName()); // 从数据库取名称
            data.setCreateBy(project.getCreateBy());
            data.setCreateTime(LocalDateTime.now()); // 从数据库取创建时间
            data.setStatus(project.getApproveStatus());
            data.setDays(Long.valueOf(project.getEstimatedHours()));
            data.setTenantId(project.getTenantId());
            //流程定义中的code
            data.setFlowCode("projectAssign");
        }

        //操作推送
        ProjectEntity project = projectMapper.selectById(bizId);
        List<Long> userIds;
        String engineerName;
        if (null != project.getAssignedEngineer()) {
            // 根据姓名反查
            EngineerEntity engineer = engineerService.getById(project.getAssignedEngineer());
            engineerName = engineer.getName();
            //SysUserVo sysUserVo = userService.selectUserByUserName(engineer.getEmployeeCode());
            userIds = userService.queryUserIds();
            //if (sysUserVo != null) userIds.add(sysUserVo.getUserId());
        } else {
            engineerName = null;
            userIds = null;
        }
        String approveStatusName = "";
        if(StringUtils.isNotBlank(project.getApproveStatus())){
            switch (project.getApproveStatus()) {
                case "0": approveStatusName ="待提交";break;
                case "1": approveStatusName ="已提交";break;
                case "9": approveStatusName ="已拒绝";break;
                case "10": approveStatusName ="审核中";break;
                case "20": approveStatusName ="已审核";break;
            }
        }
        //推送
        String content = "项目：["+project.getProjectName()+"]（响应），"+"状态["+approveStatusName+"]，负责人："+ engineerName;
        scheduledExecutorService.schedule(() -> {
            SseMessageDto dto = new SseMessageDto();
            dto.setMessage(content);
            dto.setUserIds(userIds);
            SseMessageUtils.publishMessage(dto);
        }, 2, TimeUnit.SECONDS);

        pushProjectMessage(project,userIds, content,engineerName);
        return data;
    }

    // 从返回值提取bizId（适配新增接口）
    private Long getBizIdFromResult(Object result) {
        if (result == null) {
            return null;
        }
        // 场景1：返回值是R类型（统一响应）
        if (result instanceof R) {
            R<?> r = (R<?>) result;
            Object data = r.getData(); // 获取R中的data字段
            if (data == null) {
                log.error("返回值R中的data为null");
                return null;
            }
            // 子场景1：data是Long类型（直接就是projectId）
            if (data instanceof Long) {
                return (Long) data;
            }
            // 子场景2：data是Project实体类（通过getId()获取）
            try {
                Method getIdMethod = data.getClass().getMethod("getId");
                Object idObj = getIdMethod.invoke(data);
                if (idObj instanceof Long) {
                    return (Long) idObj;
                } else if (idObj instanceof Integer) {
                    return ((Integer) idObj).longValue();
                }
            } catch (NoSuchMethodException e) {
                // 如果没有getId()方法，直接判断data是否是数字类型（如Long/Integer）
                if (data instanceof Number) {
                    return ((Number) data).longValue();
                }
                log.error("返回值data没有getId()方法，类型：{}", data.getClass().getName());
            } catch (Exception e) {
                log.error("反射获取id失败", e);
            }
        }
        return null;
    }

    private void pushProjectMessage(ProjectEntity project, List<Long> userIds,String content,String engineerName) {
        SsePushMessage push = new SsePushMessage();
        OverdueRecord overdueRecord = overdueRecordMapper.selectByBizTypeAndId(BizTypeConstant.PROJECT+"Overdue", project.getId());
        if(Objects.nonNull(overdueRecord)){
            push.setInstanceId(overdueRecord.getId());
        }
        push.setType("overdue");
        push.setMessage(content);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < userIds.size(); i++) {
            sb.append(userIds.get(i));
            // 最后一个元素后不添加逗号
            if (i != userIds.size() - 1) {
                sb.append(",");
            }
        }
        push.setUserIds(sb.toString());
        push.setMessageType(BizTypeConstant.PROJECT+"Overdue");
        push.setTenantId(project.getTenantId());
        ssePushMessageMapper.insert(push);

    }


}
